home *** CD-ROM | disk | FTP | other *** search
- //***************************************************************************
- // OATH :: Object-oriented Abstract Type Hierarchy
- //***************************************************************************
- //
- // Copyright (C) 1991, 1990 Texas Instruments Incorporated
- // Permission is granted to any individual or institution
- // to use, copy, modify, and distribute this software,
- // provided that this complete copyright and permission notice
- // is maintained, intact, in all copies and supporting documentation.
- //
- // Texas Instruments Incorporated provides this software "as is"
- // without express or implied warranty.
- //
- //***************************************************************************
- // dlList (dlListA, dlListG)
- // dlPos (dlPosA, dlPosG)
- //
- // History:
- // 07/91 Brian M Kennedy import, export, typeRegister
- // 06/91 Brian M Kennedy New macros & format; remove printDiagnostic
- // 10/90 Brian M Kennedy Major Rewrite
- // 02/90 Brian M Kennedy Original
- //
- //***************************************************************************
-
- #include "copyright.h"
-
- #include <oath/dlList.h>
-
- #include <iostream.h>
-
- /////////////////////////////////////////////////////////////////////////////
- // dlList Outlines
-
- OUTLINES(dlList, list)
-
- // Constructors //////////
-
- dlListG::
- dlListG (int IsConst)
- :listG(IsConst), Header(0), End(0), PosList(0)
- {ref();
- {End = Header = new dlNodeP;}
- deref();
- }
-
- dlListG::
- dlListG (const seqG* S, int IsConst)
- :listG(IsConst), Header(0), End(0), PosList(0)
- {ref();
- {End = Header = new dlNodeP;
- for(posA P = S->makePos(0, 0); P(); ++P)
- End = End->insertAfter((*P).guts());
- }
- deref();
- }
-
- dlListG::
- dlListG (const posG* Start, const posG* Beyond, int IsConst)
- :listG(IsConst), Header(0), End(0), PosList(0)
- {ref();
- {End = Header = new dlNodeP;
- if(Beyond->isNil())
- {for(posA P = (posA&)Start->makeCopy(0); P(); ++P)
- End = End->insertAfter((*P).guts());
- }
- else
- {ensure(Start->parent()->is(Beyond->parent()),
- "The two Pos's are not from the same Seq!");
- for(posA P = (posA&)Start->makeCopy(0);
- !Beyond->isEqual(P.guts()); ++P)
- {assumed(P(), "Second Pos is not after the first!");
- End = End->insertAfter((*P).guts());
- }
- }
- }
- deref();
- }
-
- dlListG::
- ~dlListG ()
- {ref();
- {while(Header->next())
- Header->deleteNext();
- delete Header;
- }
- deref();
- }
-
-
- // oathCore Operations //////////
-
- void dlListG::
- export (exportP& X) const
- {X.writeType(TypeName);
- int Count = count();
- X.stream() << Count << (isConst() ? ' ' : '\0');
- if(Count)
- {for(posA P = makePos(0, 0); P(); ++P)
- (*P).export(X);
- }
- }
-
- objA dlListG::
- import (importP& M)
- {int Count;
- M.stream() >> Count;
- char MakeConst = M.stream().get();
- if(Count)
- {dlNodeP * Header = new dlNodeP;
- dlNodeP * End = Header;
- for(int I = 0; I < Count; ++I)
- {objA Tmp = objA::import(M);
- End->Next = new dlNodeP (End, 0, Tmp.guts());
- End = End->Next;
- }
- return new dlListG (Header, End, MakeConst);
- }
- else
- return new dlListG (MakeConst);
- }
-
- void dlListG::
- clearReferences()
- {clearMark();
- for(dlNodeP *N = Header->next(); N; N = N->next())
- N->thisObj().guts()->deref();
- }
-
- void dlListG::
- setReferences()
- {if(!isMarked())
- {setMark();
- for(dlNodeP *N = Header->next(); N; N = N->next())
- {N->thisObj().guts()->ref();
- N->thisObj().guts()->setReferences();
- }
- }
- }
-
-
- // obj Operations //////////
-
- int dlListG::
- isEqual (const objG* O) const
- {if(is(O))
- return TRUE;
- else if(!O->isImplementedAs(Type))
- return FALSE;
- else
- {posA Pthis = makePos(0, 0);
- posA PL = ((dlListG*)O)->makePos(0, 0);
- while(TRUE)
- {if(Pthis.isPastEnd())
- return (PL.isPastEnd() ? TRUE : FALSE);
- if(PL.isPastEnd())
- return FALSE;
- if(!(*Pthis).is(*PL))
- return FALSE;
- ++Pthis;
- ++PL;
- }
- }
- }
-
- objA dlListG::
- makeCopy (int MakeConst) const
- {dlNodeP * NewHead = new dlNodeP;
- dlNodeP * NewEnd = NewHead;
- for(dlNodeP * P = Header; P->next(); P = P->next())
- NewEnd = NewEnd->insertAfter(P->nextObj().guts());
- return new dlListG (NewHead, NewEnd, MakeConst);
- }
-
- // bag Operations //////////
-
- int dlListG::
- count () const
- {int C = 0;
- for(dlNodeP *N = Header->next(); N; N = N->next())
- C++;
- return C;
- }
-
- int dlListG::
- contains (const objG* O) const
- {for(dlNodeP *N = Header->next(); N; N = N->next())
- if(O->is(N->thisObj().guts()))
- return TRUE;
- return FALSE;
- }
-
- int dlListG::
- containsEqual (const objG* O) const
- {for(dlNodeP *N = Header->next(); N; N = N->next())
- if(O->isEqual(N->thisObj().guts()))
- return TRUE;
- return FALSE;
- }
-
- int dlListG::
- canContain (const objG*) const
- {return TRUE;}
-
- void dlListG::
- insert (const objG* O)
- {NOT_CONST();
- End = End->insertAfter(O);
- }
-
- void dlListG::
- append (const bagG* B)
- {NOT_CONST();
- B->applyX(callSelf, this);
- }
-
- void dlListG::
- apply (void (*F)(objA)) const
- {for(dlNodeP *N = Header->next(); N; N = N->next())
- F(N->thisObj());
- }
-
- bagG* dlListG::
- applyX (objA (*F)(objA), bagG* B) const
- {for(dlNodeP *N = Header->next(); N; N = N->next())
- {objA O = F(N->thisObj());
- B->insert(O.guts());
- }
- return B;
- }
-
- bagG* dlListG::
- applyX (bagA (*F)(objA), bagG* B) const
- {for(dlNodeP *N = Header->next(); N; N = N->next())
- {bagA O = F(N->thisObj());
- B->append(O.guts());
- }
- return B;
- }
-
- bagA dlListG::
- makeEmpty () const
- {return new dlListG();}
-
-
- // queue Operations //////////
-
- const objG* dlListG::
- remove ()
- {NOT_CONST();
- assumed(!isEmpty(), "remove() attempted on an empty Queue!");
- adjustPosList(Header->next(), Header);
- const objG* O = Header->nextObj().guts();
- if(End == Header->next())
- End = Header;
- Header->deleteNext();
- return O;
- }
-
-
- // seq Operations //////////
-
- const objG* dlListG::
- subscript (int I) const
- {dlNodeP* N = internalPosition(I);
- assumed(N->next(), "Indexed beyond end of Seq!");
- return N->nextObj().guts();
- }
-
- const objG* dlListG::
- subscript (const posG* P) const
- {ensure(!P->isNil() && is(P->parent()), "Pos not from this Sequence!");
- return ((dlPosG*)P)->Prev->nextObj().guts();
- }
-
- seqA dlListG::
- makeSeq (const posG* Start, const posG* Beyond, int MakeConst) const
- {return new dlListG (Start, Beyond, MakeConst);}
-
- seqA dlListG::
- makeSeq (int Start, int Beyond, int MakeConst) const
- {posA S = makePos(Start,TRUE);
- posA B = makePos(Beyond,TRUE);
- return new dlListG (S.guts(), B.guts(), MakeConst);
- }
-
-
- // fifoQueue Operations //////////
-
-
- // deq Operations //////////
-
- void dlListG::
- pushFront (const objG* O)
- {NOT_CONST();
- Header->insertAfter(O);
- if(Header == End)
- End = Header->next();
- }
-
- const objG* dlListG::
- pullEnd ()
- {NOT_CONST();
- assumed(!isEmpty(), "pullEnd() attempted on an empty Queue!");
- adjustPosList(End, End->prev());
- const objG* O = End->thisObj().guts();
- End = End->prev();
- End->deleteNext();
- return O;
- }
-
-
- // list Operations //////////
-
- void dlListG::
- insertList (const listPosG* P, const objG* O)
- {NOT_CONST();
- ensure(!P->isNil() && is(P->parent()), "Pos is not from this seq!");
- ((dlPosG*)P)->Prev->insertAfter(O);
- if(((dlPosG*)P)->Prev == End)
- End = End->next();
- }
-
- const objG* dlListG::
- removeList (const listPosG* P)
- {NOT_CONST();
- ensure(!P->isNil() && is(P->parent()), "Pos is not from this seq!");
- dlNodeP* N = ((dlPosG*)P)->Prev->next();
- assumed(N, "Attempt to delete past end with remove(P,O)!");
- adjustPosList(N, ((dlPosG*)P)->Prev);
- const objG* O = ((dlPosG*)P)->Prev->nextObj().guts();
- if(N == End)
- End = End->prev();
- ((dlPosG*)P)->Prev->deleteNext();
- return O;
- }
-
-
- // dlList Operations //////////
-
- dlNodeP * dlListG::
- internalPosition (int I) const
- {if(!I)
- return Header;
- dlNodeP* N = Header;
- for(int J = 0; (J < I) && N->next(); J++)
- N = N->next();
- return N;
- }
-
- void dlListG::
- adjustPosList (dlNodeP * CurrentPrev, dlNodeP * NewPrev)
- {dlPosG * Pos = PosList;
- while(Pos)
- {if(Pos->Prev == CurrentPrev)
- Pos->Prev = NewPrev;
- Pos = Pos->NextPos;
- }
- }
-
-
- /////////////////////////////////////////////////////////////////////////////
- // dlPos Outlines
-
- OUTLINES(dlPos, listPos)
-
- // Constructors //////////
-
- dlPosG::
- dlPosG (const dlListG* iList, dlNodeP* iPrev, int IsConst)
- :listPosG(IsConst), List(iList),
- Prev(iPrev), PrevPos(0), NextPos(iList->posList())
- {if(NextPos)
- NextPos->PrevPos = this;
- List.guts()->posList() = this;
- }
-
- dlPosG::
- ~dlPosG ()
- {if(NextPos)
- NextPos->PrevPos = PrevPos;
- if(PrevPos)
- PrevPos->NextPos = NextPos;
- else
- List.guts()->posList() = NextPos;
- }
-
- // oathCore Operations //////////
-
- void dlPosG::
- export (exportP& X) const
- {X.writeType(TypeName);
- List.export(X);
- int I = 0;
- dlPosA P = List.makePos();
- while(P.guts()->Prev != Prev)
- {++P; ++I;}
- X.stream() << I << (isConst() ? ' ' : '\0');
- }
-
- objA dlPosG::
- import (importP& M)
- {dlListA L = dlListA::isa(objA::import(M));
- int I;
- M.stream() >> I;
- char MakeConst = M.stream().get();
- return L.makePos(I, MakeConst);
- }
-
- void dlPosG::
- clearReferences()
- {clearMark();
- List.guts()->deref();
- }
-
- void dlPosG::
- setReferences()
- {if(!isMarked())
- {setMark();
- List.guts()->ref();
- List.guts()->setReferences();
- }
- }
-
-
- // obj Operations //////////
-
- int dlPosG::
- isEqual (const objG* O) const
- {return O->isImplementedAs(Type) && (Prev == ((dlPosG*)O)->Prev);}
-
-
- // pos Operations //////////
-
- const objG* dlPosG::
- indirection () const
- {assumed(Prev->next(), "Access attempted past end of Sequence");
- return Prev->nextObj().guts();
- }
-
- void dlPosG::
- increment ()
- {NOT_CONST();
- if(Prev->next())
- Prev = Prev->next();
- }
-
- void dlPosG::
- increment (int I)
- {NOT_CONST();
- for(int J = 0; (J < I) && Prev->next(); J++)
- Prev = Prev->next();
- }
-
- const objG* dlPosG::
- find (const objG* O)
- {NOT_CONST();
- dlNodeP * P = Prev;
- dlNodeP * N;
- while(N = P->next())
- {if(O->is(N->thisObj().guts()))
- {Prev = P;
- return O;
- }
- P = N;
- }
- return objG::Nil;
- }
-
- const objG* dlPosG::
- findEqual (const objG* O)
- {NOT_CONST();
- dlNodeP * P = Prev;
- dlNodeP * N;
- while(N = P->next())
- {if(O->isEqual(N->thisObj().guts()))
- {Prev = P;
- return O;
- }
- P = N;
- }
- return objG::Nil;
- }
-
- void dlPosG::
- reset (const posG* P)
- {NOT_CONST();
- ensure(P->isImplementedAs(Type) && List.is(((dlPosG*)P)->List),
- "Pos's not from same seq!");
- Prev = ((dlPosG*)P)->Prev;
- }
-
- void dlPosG::
- reset (int I)
- {NOT_CONST();
- Prev = List.guts()->internalPosition(I);
- }
-
-
- // listPos Operations //////////
-
- void dlPosG::
- decrement ()
- {NOT_CONST();
- if(Prev->prev())
- Prev = Prev->prev();
- }
-
- void dlPosG::
- decrement (int I)
- {NOT_CONST();
- for(int J = 0; (J < I) && Prev->prev(); J++)
- Prev = Prev->prev();
- }
-
- //***************************************************************************
-